﻿using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.Logss;
using HamcoWcs.Entitys.PlayBacks;
using HamcoWcs.Models.Common;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Service.Common;
using HamcoWcs.Service.Mes;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Quartz;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using static Org.BouncyCastle.Math.EC.ECCurve;

namespace HamcoWcs.Main.SingalRFiles
{
    /// <summary>
    /// 
    /// </summary>
    [DisallowConcurrentExecution]
    [AutoInject(typeof(IJob), InjectType.Worker)]
    public class MonitorWorker : IJob
    {
        private readonly IHubContext<MonitorHub> _monitorContext;
        private readonly IMonitorBaseService _monitorBaseService;
        private readonly IBaseConfigService _baseConfigService;
        private readonly WcsDbContext _wcsDbContext;
        private static JsonSerializerSettings JSON_SERIALIZER_SETTINGS = new JsonSerializerSettings()
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Formatting = Formatting.None
        };
        /// <summary>
        /// 
        /// </summary>
        /// <param name="monitorContext"></param>
        /// <param name="wcsDbContext"></param>
        /// <param name="monitorBaseService"></param>
        public MonitorWorker(IHubContext<MonitorHub> monitorContext, WcsDbContext wcsDbContext, IMonitorBaseService monitorBaseService, IBaseConfigService baseConfigService)
        {
            _monitorContext = monitorContext;
            _wcsDbContext = wcsDbContext;
            _monitorBaseService = monitorBaseService;
            _baseConfigService = baseConfigService;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Execute(IJobExecutionContext context)
        {
            var data = _monitorBaseService.GetMonitorData();

            data.MesControlState = GlobalValue.MesOnlineFlag ? 1 : 0;
            //data.MesControlState = 1;
            var bwcsStateStr = _baseConfigService.TryGetConfigValue("WCSConnectState", out string wcsStateStr);
            if (wcsStateStr == "2")
            {
                data.WcsState = 2;
            }
            else
            {
                data.WcsState = 1;
            }

            //data.WcsState = 1;
            var a1 = _baseConfigService.TryGetConfigValue("CJSTW100CONTROLSTATE", out string state1);
            var a2 = _baseConfigService.TryGetConfigValue("CJSTW200CONTROLSTATE", out string state2);
            var s100 = _baseConfigService.TryGetConfigValue("CJSTW100STATE", out string state100);
            var s200 = _baseConfigService.TryGetConfigValue("CJSTW200STATE", out string state200);

            if (a1) data.CJSTW100CONTROLSTATE = state1;
            if (a2) data.CJSTW200CONTROLSTATE = state2;
            if (s100) data.CJSTW100STATE = state100;
            if (s200) data.CJSTW200STATE = state200;

            data.DeviceErrorCount = _wcsDbContext.DeviceErrorQueues.Count();
            try
            {
                int timeout = 30;
                _baseConfigService.TryGetConfigValue("TASK_TIMEOUT_THRESHOLD", out string value);
                if (!value.IsNullOrEmpty() && value != "0")
                {
                    timeout = int.Parse(value);
                }
                data.MainTaskTimeOutCount = _wcsDbContext.MainTasks.Where(x => x.CreatedTime.AddMinutes(timeout) < DateTime.Now).Count();
            }
            catch (Exception)
            {

            }
            string content = "";
            try
            {
                content = JsonConvert.SerializeObject(data, JSON_SERIALIZER_SETTINGS);
                await _monitorContext.Clients.All.SendAsync("WcsMoniorData", data);
            }
            catch (Exception ex)
            {
            }

            var time = DateTime.Now;

            var fileContent = $"{time:yyyyMMddHHmmss}|{content}";
            // 文件名
            var logFileName = Path.Combine(_playBackFolder, $"{time:yyyyMMddHH}");
            if (!File.Exists(logFileName))
            {
                var fs = new FileStream(logFileName, FileMode.CreateNew, FileAccess.ReadWrite);
                fs.Close();
            }

            bool isLog = false;

            try
            {
                File.AppendAllLines(logFileName, new List<string>()
                {
                    fileContent
                });
                isLog = true;
            }
            catch (Exception)
            {
                isLog = false;
            }


            if (!isLog)
            {
                BufferContent.Enqueue(fileContent);
            }

            if (BufferContent.Count > 0)
            {
                var _fileContent = BufferContent.Dequeue();
                try
                {
                    File.AppendAllLines(logFileName, new List<string>()
                    {
                        _fileContent
                    });
                    isLog = true;
                }
                catch (Exception)
                {
                    isLog = false;
                }

                if (!isLog) BufferContent.Enqueue(fileContent);
            }

        }




        static Queue<string> BufferContent = new Queue<string>()
        {

        };
        static string _basePath;
        static string _logFolder;
        static string _playBackFolder;
        static string _communicationFolder;
        //static JsonSerializerSettings UIJsonSettings = new JsonSerializerSettings()
        //{
        //    ContractResolver = new LongNameContractResolver()
        //    {
        //        NamingStrategy = new CamelCaseNamingStrategy()
        //    }
        //};

        static MonitorWorker()
        {

            _basePath = AppDomain.CurrentDomain.BaseDirectory;
            _logFolder = Path.Combine(_basePath, "logs");
            _playBackFolder = Path.Combine(_logFolder, "playback_logs");
            _communicationFolder = Path.Combine(_logFolder, "communication_logs");
            if (!Directory.Exists(_logFolder))
            {
                Directory.CreateDirectory(_logFolder);
                Directory.CreateDirectory(_playBackFolder);
                Directory.CreateDirectory(_communicationFolder);
            }
        }
    }
}
